#pragma once

#include <string>
#include <vector>

#include <ipc_message_parcel.h>
#include <refbase.h>
#include <ipc_service_registry.h>

class IpcServer : public RefBase {
public:
    struct IpcClient {
    public:
        int pid;
        int cid;

        IpcClient(IpcMessageParcel &parcel)
        {
            pid = parcel.callingPid;
            cid = parcel.callingCid;
        }

        bool operator <(const IpcClient &client) const
        {
            return pid != client.pid ? pid < client.pid : cid < client.cid;
        }
    };

    static const sptr<IpcServer> &GetInstance();
    void SetRegistry(IpcServiceRegistry &registry);
    int Start(int port);
    void Run();
    void Stop();

    int Send(IpcMessageParcel &parcel, struct IpcClient);

private:
    IpcServer() = default;
    virtual ~IpcServer() = default;
    static inline sptr<IpcServer> instance = nullptr;

    int ProcessPollFds();

    int socketFd = -1;
    int interruptFd = -1;
    std::vector<struct pollfd> pollfds;
    std::map<struct IpcClient, int> clientfds;
    IpcServiceRegistry *registry_;
};
